package com.lrs.java.j2se_advanced.codec;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

public class SignalGenerator {

	public static void main(String[] args) throws Exception {
		
		List<ConfigPair> config = getConfig();
		List<String[]> data = getDataList();
		
		List<StringBuilder> results = buildBinaryData(config, data);
		
		FileOutputStream fos = new FileOutputStream("result.txt");
		PrintWriter print = new PrintWriter(fos);
		for(StringBuilder result : results) {
			System.out.println(result.toString());
			print.println(result.toString());
		}
		print.flush();
	}

	private static List<StringBuilder> buildBinaryData(List<ConfigPair> config, List<String[]> datas) {
		int index=0;
		List<StringBuilder> results = new ArrayList<StringBuilder>();
		for(int idx=0;idx<datas.get(0).length;idx++){
			StringBuilder builder = new StringBuilder();
			results.add(builder);
		}
		
		for(ConfigPair pair : config) {
			if(pair.getName().equalsIgnoreCase("PlaceHolder")) {
				for(StringBuilder builder : results) {
					builder.append("00000000".substring(0, pair.getLength()));
				}
			} else {
				String[] dataArr = datas.get(index++);
				for(int i=0; i<dataArr.length; i++) {
					hex2ByteStr(results.get(i), pair, dataArr[i]);
				}
			}
		}
		
		return results;
	}

	private static void hex2ByteStr(StringBuilder result, ConfigPair pair, String hex) {
		
		String byteStr = Integer.toBinaryString(Integer.valueOf(hex, 16));
		if(byteStr.length() < pair.getLength()) {
			byteStr = "00000000000000000000000000000000".substring(0, pair.getLength()-byteStr.length()) + byteStr;
		} else if(byteStr.length() > pair.getLength()) {
			throw new RuntimeException("length out of oubound" + pair.getName() + ":" + pair.getLength() + " invalid value : " + hex);
		}
		result.append(byteStr);
	}
	
	
	private static List<ConfigPair> getConfig() throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				SignalGenerator.class.getResourceAsStream("config.txt")));
		
		List<ConfigPair> config = new ArrayList<ConfigPair>();
		String str;
		while((str=reader.readLine()) != null) {
//			System.out.println(str);
			String[] pairs = str.split(":");
			config.add(new ConfigPair(pairs[0], Integer.parseInt(pairs[1])));
		}
//		System.out.println(config);
		
		return config;
	}
	
	public static List<String[]> getDataList() throws IOException{
		BufferedReader reader =null;
		/**
		 * 通过类路径读取配置文件，文件和类在从一个package中
		 */
		reader = new BufferedReader(new InputStreamReader(
				SignalGenerator.class.getResourceAsStream("data.txt")));

		
		/**
		 * 通过classLoader读取配置文件，相对于类路径的根目录(com平行目录)
		 */
//		reader = new BufferedReader(new InputStreamReader(
//				Thread.currentThread().getContextClassLoader().getResourceAsStream("data.txt")));
		

		/**
		 * 使用文件系统，读取JAR外的文件系统（相对Jar文件的目录)
		 */
//		reader = new BufferedReader(new InputStreamReader(
//				new FileInputStream("data.txt")));
		
		List<String[]> dataList = new ArrayList<String[]>();
		String str;
		while((str=reader.readLine()) != null) {
//			System.out.println(str);
			dataList.add(str.split(","));
		}
//		System.out.println(dataList);
		
		return dataList;
	}
	
	static class ConfigPair {
		private String name;
		private int length;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public int getLength() {
			return length;
		}
		public void setLength(int length) {
			this.length = length;
		}
		public ConfigPair(String name, int length) {
			super();
			this.name = name;
			this.length = length;
		}
		
	}
	
	
}
